package com.sheliduan.itlearning.common.domain.mapper;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sheliduan.itlearning.common.domain.dos.UserBoughtCourseDO;
import com.sheliduan.itlearning.common.domain.dos.UserCollectDO;
import com.sheliduan.itlearning.common.domain.dos.VideoCourseDO;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;

/**
 * @author: 断舍离
 * @date: 2025/4/16 10:44
 * @description: 用户已购买课程映射接口
 **/
public interface UserBoughtCourseMapper extends BaseMapper<UserBoughtCourseDO> {

    /*
     * 根据查询条件分页查询课程数据
     * */
    default Page<UserBoughtCourseDO> selectPageList(long current, long size, String username, Integer bloggerId, LocalDateTime startDate, LocalDateTime endDate){
        // MyBatis分页对象, 需传入当前页码和每页记录数
        Page<UserBoughtCourseDO> page = new Page<>(current, size);
        LambdaQueryWrapper<UserBoughtCourseDO> wrapper = new LambdaQueryWrapper<>();
        wrapper
                .eq(UserBoughtCourseDO::getBloggerId, bloggerId)
                .ge(Objects.nonNull(startDate), UserBoughtCourseDO::getOrderTime, startDate) // 大于等于 startDate
                .le(Objects.nonNull(endDate), UserBoughtCourseDO::getOrderTime, endDate)// 小于等于 endDate
                .orderByDesc(UserBoughtCourseDO::getOrderTime);
        Page<UserBoughtCourseDO> userBoughtCourseDOPage = selectPage(page, wrapper);
        List<UserBoughtCourseDO> distinctPage = userBoughtCourseDOPage.getRecords().stream().filter(distinctByKey(UserBoughtCourseDO::getUserId)).collect(Collectors.toList());
        userBoughtCourseDOPage.setRecords(distinctPage);
        userBoughtCourseDOPage.setTotal(distinctPage.size());
        return userBoughtCourseDOPage;
    }

    public static <T> Predicate<T> distinctByKey(Function<? super T, Object> keyExtractor) {
        Map<Object, Boolean> seen = new ConcurrentHashMap<>(); // 支持并行流
        return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
    }
}
